package pixelradar.util;

import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.resources.I18n;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.chunk.Chunk;
import pixelradar.config.Config;

import java.io.File;
import java.lang.reflect.Field;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

public class Utils {
    private static final int[] COLOURS = new int[]{16711680, 65280, 255, 16776960, 16711935, 65535, 16744448, 8388863};
    public static String RealmsWorldName = "";
    public static int colourIndex = 0;

    public static boolean judgeFloat(float a, float b) {
        return (double) Math.abs(a - b) < 1.0E-6D;
    }

    public static int[] integerListToIntArray(List<Integer> list) {
        int size = list.size();
        int[] array = new int[size];

        for (int i = 0; i < size; ++i) {
            array[i] = (Integer) list.get(i);
        }

        return array;
    }

    public static String mungeString(String s) {
        s = s.replace('.', '_');
        s = s.replace('-', '_');
        s = s.replace(' ', '_');
        s = s.replace('/', '_');
        s = s.replace('\\', '_');
        return Reference.patternInvalidChars.matcher(s).replaceAll("");
    }

    public static String mungeStringForConfig(String s) {
        return Reference.patternInvalidChars2.matcher(s).replaceAll("");
    }

    public static File getFreeFilename(File dir, String baseName, String ext) {
        int i = 0;
        File outputFile;
        if (dir != null) {
            outputFile = new File(dir, baseName + "." + ext);
        } else {
            outputFile = new File(baseName + "." + ext);
        }

        for (; outputFile.exists() && i < 1000; ++i) {
            if (dir != null) {
                outputFile = new File(dir, baseName + "." + i + "." + ext);
            } else {
                outputFile = new File(baseName + "." + i + "." + ext);
            }
        }

        return i < 1000 ? outputFile : null;
    }

    public static void printBoth(String msg) {
        EntityPlayerSP player = Minecraft.getMinecraft().player;
        if (player != null) {
            player.sendStatusMessage(new TextComponentString(msg), false);
        }

        Logging.log("%s", msg);
    }

    public static IntBuffer allocateDirectIntBuffer(int size) {
        if (size < 1) {
            int newSize = Minecraft.getGLMaximumTextureSize();
            return ByteBuffer.allocateDirect(newSize * newSize * 4).order(ByteOrder.nativeOrder()).asIntBuffer();
        } else {
            return ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder()).asIntBuffer();
        }
    }

    public static int nextHighestPowerOf2(int v) {
        --v;
        v |= v >> 1;
        v |= v >> 2;
        v |= v >> 4;
        v |= v >> 8;
        v |= v >> 16;
        return v + 1;
    }

    public static String getCurrentDateString() {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
        return dateFormat.format(new Date());
    }

    public static int distToChunkSq(int x, int z, Chunk chunk) {
        int dx = (chunk.x << 4) + 8 - x;
        int dz = (chunk.z << 4) + 8 - z;
        return dx * dx + dz * dz;
    }

    public static String loadServerName() {
        String serverName;
        if (Minecraft.getMinecraft().isIntegratedServerRunning()) {
            IntegratedServer server = Minecraft.getMinecraft().getIntegratedServer();
            serverName = server != null ? server.getFolderName() : "sp_world";
        } else if (Minecraft.getMinecraft().isConnectedToRealms()) {
            if (!"".equals(RealmsWorldName)) {
                serverName = RealmsWorldName;
            } else {
                serverName = "Realms";
            }
        } else {
            serverName = ((ServerData) Optional.ofNullable(Minecraft.getMinecraft().getCurrentServerData()).orElse(new ServerData("anonymous_server", "", false))).serverIP;
            if (!Config.portNumberInWorldNameEnabled) {
                serverName = serverName.substring(0, serverName.indexOf(":"));
            } else if (!serverName.contains(":")) {
                serverName = serverName + "_25565";
            } else {
                serverName = serverName.replace(":", "_");
            }
        }

        serverName = mungeString(serverName);
        if ("".equals(serverName)) {
            serverName = "default";
        }

        return serverName;
    }

    public static void openWebLink(URI url) {
        try {
            Class<?> oclass = Class.forName("java.awt.Desktop");
            Object object = oclass.getMethod("getDesktop").invoke((Object) null);
            oclass.getMethod("browse", URI.class).invoke(object, url);
        } catch (Throwable var3) {
            Logging.logError("Couldn't open link %s", Arrays.toString(var3.getStackTrace()));
        }

    }

    public static String stringArrayToString(String[] arr) {
        StringBuilder builder = new StringBuilder();
        String[] var2 = arr;
        int var3 = arr.length;

        for (int var4 = 0; var4 < var3; ++var4) {
            String s = var2[var4];
            builder.append(I18n.format(s, new Object[0]));
            builder.append("\n");
        }

        return builder.toString();
    }

    public static int getMaxWidth(String[] arr, String[] arr2) {
        FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRenderer;
        int width = 1;

        for (int i = 0; i < arr.length; ++i) {
            int w2 = 0;
            String s = I18n.format(arr[i], new Object[0]);
            int w1 = fontRendererObj.getStringWidth(s);
            if (arr2 != null && i < arr2.length) {
                s = I18n.format(arr2[i], new Object[0]);
                w2 = fontRendererObj.getStringWidth(s);
                w2 += 65;
            }

            int wTot = Math.max(w1, w2);
            width = Math.max(width, wTot);
        }

        return width;
    }

    private static int getColoursLength() {
        return COLOURS.length;
    }

    public static int getCurrentColour() {
        return -16777216 | COLOURS[colourIndex];
    }

    public static int getNextColour() {
        colourIndex = (colourIndex + 1) % getColoursLength();
        return getCurrentColour();
    }

    public static int getPrevColour() {
        colourIndex = (colourIndex + getColoursLength() - 1) % getColoursLength();
        return getCurrentColour();
    }

    public static <K, V> Map<K, V> checkedMapByCopy(Map rawMap, Class<K> keyType, Class<V> valueType, boolean strict) throws ClassCastException {
        Map<K, V> m2 = new HashMap(rawMap.size() * 4 / 3 + 1);
        Iterator var5 = rawMap.entrySet().iterator();

        while (var5.hasNext()) {
            Object o = var5.next();
            Entry e = (Entry) o;

            try {
                m2.put(keyType.cast(e.getKey()), valueType.cast(e.getValue()));
            } catch (ClassCastException var9) {
                if (strict) {
                    throw var9;
                }

                System.out.println("not assignable");
            }
        }

        return m2;
    }

    public static Field findUnderlying(Class<?> clazz, String fieldName) {
        Class current = clazz;

        while (true) {
            try {
                return current.getDeclaredField(fieldName);
            } catch (Exception var4) {
                if ((current = current.getSuperclass()) == null) {
                    return null;
                }
            }
        }
    }

    private static String[] getLocalizedStringArray(String[] str, String translateKey) {
        String[] res = new String[str.length];

        for (int i = 0; i < str.length; ++i) {
            res[i] = "".equals(str[i]) ? "" : I18n.format(translateKey + str[i].toLowerCase(), new Object[0]);
        }

        return res;
    }

    public static String[] getLocalizedBgModeArray(String[] mode) {
        return getLocalizedStringArray(mode, "mw.config.backgroundTextureMode.");
    }

    public static String[] getLocalizedHelpText(String[] str) {
        return getLocalizedStringArray(str, "mw.gui.mwgui.helptext.");
    }

    public static String[] getLocalizedHelpTextKey(String[] str) {
        String[] res = getLocalizedStringArray(str, "mw.gui.mwgui.helptext.key.");

        for (int i = 2; i < res.length; ++i) {
            res[i] = "  " + res[i];
        }

        return res;
    }

    public static <T> List<T> castList(Object obj, Class<T> clazz) {
        List<T> result = new ArrayList<>();
        if (obj instanceof List) {
            for (Object o : (List) obj) {
                result.add(clazz.cast(o));
            }
        }

        return result;
    }
}
